# import io
#
# from django.contrib.auth.models import User
# from django.http import HttpResponse
# from django.shortcuts import render
#
# # Create your views here.
# from django.views import View
# from django_redis import get_redis_connection
# from requests import Response
# from rest_framework.mixins import RetrieveModelMixin
# from rest_framework.permissions import IsAuthenticated
# from rest_framework.status import HTTP_404_NOT_FOUND
# from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet
#
# from config.dbs.redis_dev import LOGIN_KEY_TEMPLATE, EXPIRE_TIME
# from users.serializers import *
# from utils.permission import ActiveUserPermission, wrap_permisssion, TeacherPermission
# from utils.verifyUtil import ImageVerify
#
# # 导入日志器
# # logger = logging.getLogger(__name__)
#
#
#
# class ImageVerifyView(View):
#     """
#     图片验证码视图类
#     get
#     返回图片验证码
#     """
#
#     def get(self, request, uuid):
#         """
#         返回验证码图片
#         :param request: 请求对象
#         :param uuid: 客户端的唯一标识
#         :return:
#         """
#         imgVerify = ImageVerify()
#         img, code = imgVerify.verify_code()
#
#         # 将图片数据返回给客户端， 无需持久化，所以用流，因为图片为字节数据，所以用字节流
#         img_bytes = io.BytesIO()
#         img.save(img_bytes, format='PNG')
#         image_bytes = img_bytes.getvalue()  # 图片的字节数据
#         cache = get_redis_connection(alias='verify_codes')
#         cache.set(LOGIN_KEY_TEMPLATE % uuid, code, EXPIRE_TIME)
#
#         # print(code)  # 谁的验证码答案是什么 如何保存 uuid:zahs key-value 临时数据，所以缓存在redis中
#         return HttpResponse(image_bytes, content_type='image/png')
#
#
# class UserViewSet(ReadOnlyModelViewSet):
#     # 拥有查询集和序列化器继承GenericViewSet
#     """
#     update:
#     更新用户个人信息
#     前端传入的数据格式：
#     {
#     ‘first_name’:‘张三’，
#     ‘email‘:zs@maqujiaoyu.com,
#     'userdetail':
#         {
#             'age':'18'
#             'sex': 1
#         }
#     }
#     """
#     queryset = User.objects.filter()
#     serializer_class = UserSerializer
#     permission_classes = [IsAuthenticated]
#
#     @wrap_permisssion(TeacherPermission)
#     def list(self, request, *args, **kwargs):
#         return ReadOnlyModelViewSet.list(self, request, *args, **kwargs)
#
#     @wrap_permisssion(ActiveUserPermission)
#     def retrieve(self, request, *args, **kwargs):
#         return ReadOnlyModelViewSet.retrieve(self, request, *args, **kwargs)
#
#     @wrap_permisssion(ActiveUserPermission)
#     def update(self, request, pk):
#         # 得到用户 user
#         try:
#             user = self.get_queryset().get(id=pk)
#         except User.DoesNotExist:
#             return Response(status=HTTP_404_NOT_FOUND)
#
#         # 得到用户输入的的信息进行反序列化
#         user_serializer = self.get_serializer(user, data=request.data)
#         # 校验
#         # 修改user表信息
#         user_serializer.is_valid(raise_exception=True)
#         user_serializer.save()
#         # 判断用户是否有详情信息
#         user_detail = request.data.get('userdetail')
#         if user_detail:
#             if hasattr(user, 'userdetail'):
#                 # 如果有，则修改
#                 user_detail_serializer = UserDetailSerializer(user.userdetail, data=user_detail)
#             # 如果没有， 则创建
#             else:
#                 user_detail['user'] = pk
#                 user_detail_serializer = UserDetailSerializer(data=user_detail)
#             user_detail_serializer.is_valid(raise_exception=True)
#             user_detail_serializer.save()
#
#             user_serializer.data['userdetail'] = user_detail_serializer.data
#         # 返回修改后的数据
#         return Response(user_serializer.data)  # 字典的赋值


import io
import logging

from django.contrib.auth.models import User
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.status import HTTP_404_NOT_FOUND, HTTP_400_BAD_REQUEST, HTTP_500_INTERNAL_SERVER_ERROR
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.permissions import IsAuthenticated
from config.fastdfsConfig import FASTDFS_SERVER_DOMAIN
from fdfs_client.client import Fdfs_client, get_tracker_conf

from config.dbs.redis_dev import LOGIN_KEY_TEMPLATE, EXPIRE_TIME
from utils.permission import ActiveUserPermission, wrap_permisssion, TeacherPermission
from utils.verifyUtil import ImageVerify
from .serializers import *

# 导入日志器
logger = logging.getLogger(__name__)

# 创建FastDFS客户端对象
tracker_path = get_tracker_conf('utils/fastdfs/client.conf')
client = Fdfs_client(tracker_path)


class ImageVerifyView(View):
    """
    图片验证码视图类

    get
    返回图片验证码
    """

    def get(self, request, uuid):
        """
        返回验证码图片
        :param request: 请求对象
        :param uuid: 客户端的唯一标识
        :return:
        """
        imgVerify = ImageVerify()
        img, code = imgVerify.verify_code()

        # 将图片数据返回给客户端，无需持久化，所以用流，因为是图片，是字节数据，所以用字节流
        img_bytes = io.BytesIO()
        img.save(img_bytes, format='PNG')
        image_bytes = img_bytes.getvalue()  # 图片的字节数据

        # print(code) # 如何保存 uuid:ZFhA key-value 临时数据 缓存在redis中
        cache = get_redis_connection(alias='verify_codes')
        cache.set(LOGIN_KEY_TEMPLATE % uuid, code, EXPIRE_TIME)

        return HttpResponse(image_bytes, content_type='image/png')


class UserViewSet(ReadOnlyModelViewSet):
    """
    update:
    更新用户个人信息
    前端传入的数据格式：
    {
    'first_name':'张三',
    'email':'zs@maqujiaoyu.com'
    'userdetail':
        {
            'age':18,
            'sex':1
        }
    }
    """
    queryset = User.objects.filter(is_active=1)
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

    def get_serializer(self, *args, **kwargs):
        if self.action == 'password':
            return UpdatePasswordSerializer(*args, **kwargs)
        return self.serializer_class(*args, **kwargs)

    @wrap_permisssion(TeacherPermission)
    def list(self, request, *args, **kwargs):
        return ReadOnlyModelViewSet.list(self, request, *args, **kwargs)

    @wrap_permisssion(ActiveUserPermission)
    def retrieve(self, request, *args, **kwargs):
        return ReadOnlyModelViewSet.retrieve(self, request, *args, **kwargs)

    @wrap_permisssion(ActiveUserPermission)
    def update(self, request, pk):
        # 得到用户 user
        try:
            user = self.get_queryset().get(id=pk)
        except User.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        # 得到用户输入的数据进行反序列化
        user_serializer = self.get_serializer(user, data=request.data)
        # 校验
        user_serializer.is_valid(raise_exception=True)
        # 修改user表信息
        user_serializer.save()  # 修改instance,data

        # 判断用户是否传入详情信息
        user_detail = request.data.get('userdetail')  # 获取用户传入的详情数据
        if user_detail:
            # 有，判断用户是否有详情信息,判断数据库里面有没有
            if hasattr(user, 'userdetail'):
                # 如果有，则修改
                user_detail_serializer = UserDetailSerializer(user.userdetail, data=user_detail)
            else:
                # 如果没有，则创建
                user_detail['user'] = pk
                user_detail_serializer = UserDetailSerializer(data=user_detail)
            user_detail_serializer.is_valid(raise_exception=True)
            user_detail_serializer.save()

            user_serializer.data['userdetail'] = user_detail_serializer.data  # 字典的赋值 dict[key] = value
        # 返回修改后的数据
        return Response(user_serializer.data)

    @action(methods=['post'], detail=True)
    def avatar(self, request, pk):
        # 得到操作的用户对象
        try:
            user = self.get_queryset().get(id=pk)
        except User.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        # 得到上传的文件数据
        file = request.FILES.get('file')
        # 判断是否有数据， 文件类型是否是图片
        if not file or file.content_type not in ('image/jpeg', 'image/png', 'image/gif'):
            # 不是，返回客户端传入数据错误
            return Response(status=HTTP_400_BAD_REQUEST)
        # 是， 交给fastdfs， 存储到可用的storage服务上
        # 得到文件后缀名，如果没有后缀名则默认为png类型
        try:
            images_ext_name = file.name.split('.')[-1]
        except Exception as e:
            logger.info('图片拓展名异常： %s' % e)
            images_ext_name = 'png'

        # 上传图片数据，通过字节流
        try:
            upload_res = client.upload_by_buffer(file.read(), file_ext_name=images_ext_name)
        except Exception as e:
            logger.error('图片上传出现异常：%s' % e)
            return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            if upload_res.get('status') != 'Upload successed.':
                logger.warning('图片上传失败')
                return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)

            # 得到返回的file_id
            image_name = upload_res.get('Remote file_id').decode()
            image_url = FASTDFS_SERVER_DOMAIN + image_name
        # 判断是否有详情数据
        if hasattr(user, 'userdetail'):
            # 如果有，则修改头像字段，保存图片信息
            user_detail = user.userdetail  # 得到当前操作用户的用户详情模型对象
            user_detail.avatar = image_url
            user_detail.save()
        else:
            # 如果没有，则创建详情， 保存图片信息
            UserDetail.objects.create(avator=image_url, user=user)
        # 返回图片地址
        return Response({'data': image_url})

    # 得到要操作的用户对象
    # 检查原始密码是否正确
    # 错误，返回提示，原密码错误
    # 正确 修改密码
    @action(methods=['put'], detail=True)
    def password(self, request, pk):
        try:
            user = self.get_queryset().get(id=pk)
        except User.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        password = request.data['password']
        new_password = request.data['new_password']
        if user.check_password(password):
            user.set_password(new_password)
            user.save()
            return Response({'msg': '修改成功'})
        else:
            return Response(status=HTTP_400_BAD_REQUEST)
